package com.zzj.ecology.framework.configuration.security.filter;

import com.google.code.kaptcha.Constants;
import com.zzj.ecology.framework.exception.CaptchaException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义 验证码 验证过滤器
 *
 * 在验证用户名密码前，先验证 验证码
 *
 * 需要在 CustomizingSpringSceurityConfiguration.class 的 protected void configure(HttpSecurity http) throws Exception 方法中 添加
 *  http.addFilterBefore(loginAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
 *
 * Spring Security 提供了一个UsernamePasswordAuthenticationFilter 的过滤器作为默认的用户登录过滤器，但是只能对用户名和密码进行校验
 * 实现当用户登录对的时候都必须输入验证码，如果验证码没有通过校验会提示验证码输入有误，当验证码被校验后才进行用户和密码的校验
 *
 * 使用LoginAuthenticationFilter替换原有的用户名密码认证凡是，需要删除http.formLogin，因为http.formLogin会创建一个LoginAuthenticationFilter
 *
 */
//@Component("loginAuthenticationFilter") // 在 CustomizingSpringSceurityConfiguration.class 中创建
public class LoginAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    /**
     * 登入成功 处理器
     */
//    @Autowired
//    private CustomizeAuthenticationSuccessHandler customizeAuthenticationSuccessHandler;
//    /**
//     * 登入失败 处理器
//     */
//    @Autowired
//    private CustomizeAuthenticationFailureHandler customizeAuthenticationFailureHandler;

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        //获取表单提交的验证码的值
        String codeInRequest = request.getParameter("verifyCode");//与页面上的name一致
        //获取下发的存在session中的验证码的值
        String codeInSession = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (StringUtils.isEmpty(codeInRequest)){
            throw new CaptchaException("未填写验证码");
        }else  if (!codeInSession.contentEquals(codeInRequest)) {
            throw new CaptchaException("验证码不匹配");
        }
        //调用UsernamePasswordAuthenticationFilter的认证方法
        return super.attemptAuthentication(request, response);
    }
}
